﻿/*
 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 * 页面的Lambda表达式部分非常有特点,本页面禁止删除
 */

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Linq.Expressions;
//using System.Reflection;
//using System.Reflection.Emit;

//namespace Framework.Common.Reflection
//{

//    /// <summary>
//    /// 
//    /// </summary>
//    public static class FunctionFactory
//    {
//        #region Nested type: IL

//        public static class IL
//        {
//            public static object CreateInstance(Type type)
//            {
//                Func<object> handler =
//                    DynamicMethodCompiler.CreateInstantiateObjectHandler(type);
//                return handler();
//            }

//            public static Action<object, object> CreateSetHandler(PropertyInfo propertyInfo)
//            {
//                Action<object, object> setHandler = DynamicMethodCompiler.CreateSetHandler(propertyInfo);
//                return setHandler;
//            }

//            public static Func<object, object> CreateGetHandler(PropertyInfo propertyInfo)
//            {
//                Func<object, object> getHandler = DynamicMethodCompiler.CreateGetHandler(propertyInfo);
//                return getHandler;
//            }
//        }

//        #endregion

//        #region Nested type: Lambda

//        public static class Lambda
//        {
//            public static T CreateInstance<T>()
//            {
//                return InstanceCreator<T>.CreateInstance();
//            }

//            public static List<T> CreateListInstance<T>()
//            {
//                return InstanceCreator<T>.CreateListInstance();
//            }

//            public static Action<T, TValue> BuildSet<T, TValue>(string property)
//            {
//                string[] props = property.Split('.');
//                Type type = typeof(T);
//                ParameterExpression arg = Expression.Parameter(type, "x");
//                ParameterExpression valArg = Expression.Parameter(typeof(TValue), "val");
//                Expression expr = arg;
//                foreach (string prop in props.Take(props.Length - 1))
//                {
//                    // use reflection (not ComponentModel) to mirror LINQ 
//                    PropertyInfo pi = type.GetProperty(prop);
//                    expr = Expression.Property(expr, pi);
//                    type = pi.PropertyType;
//                }
//                // final property set...
//                PropertyInfo finalProp = type.GetProperty(props.Last());
//                MethodInfo setter = finalProp.GetSetMethod();
//                expr = Expression.Call(expr, setter, valArg);
//                return Expression.Lambda<Action<T, TValue>>(expr, arg, valArg).Compile();
//            }

//            public static Func<T, TValue> BuildGet<T, TValue>(string property)
//            {
//                string[] props = property.Split('.');
//                Type type = typeof(T);
//                ParameterExpression arg = Expression.Parameter(type, "x");
//                Expression expr = arg;
//                foreach (string prop in props)
//                {
//                    // use reflection (not ComponentModel) to mirror LINQ 
//                    PropertyInfo pi = type.GetProperty(prop);
//                    expr = Expression.Property(expr, pi);
//                    type = pi.PropertyType;
//                }
//                return Expression.Lambda<Func<T, TValue>>(expr, arg).Compile();
//            }

//            /// <summary>
//            /// Creates a compiled delegate function for the specified type and method name
//            /// </summary>
//            /// <typeparam name="TFunc">Delegate Func to create</typeparam>
//            /// <param name="obj">Constant to get method from</param>
//            /// <param name="methodName">Method to examine</param>
//            /// <returns>Delegate function of the specified methodname</returns>
//            public static TFunc CreateFunc<TFunc>(object obj, string methodName)
//            {
//                var args = new List<ParameterExpression>();

//                Type targetType = obj.GetType();
//                MethodInfo minfo = targetType.GetMethod(methodName,
//                                                        BindingFlags.Instance | BindingFlags.Public |
//                                                        BindingFlags.SetProperty);

//                if (minfo != null)
//                {
//                    ConstantExpression target = Expression.Constant(obj);
//                    foreach (ParameterInfo arg in minfo.GetParameters())
//                        args.Add(Expression.Parameter(arg.ParameterType, arg.Name));
//                    MethodCallExpression methodinvokeExpression = Expression.Call(target, minfo, args.ToArray());
//                    Expression<TFunc> lambda = Expression.Lambda<TFunc>(methodinvokeExpression, args.ToArray());

//                    //now the following Lambda is created:
//                    // (TArg1, TArg2) => obj.MethodName(TArg1, TArg2);

//                    return lambda.Compile();
//                }
//                return default(TFunc);
//            }

//            /// <summary>
//            /// Creates a compiled delegate function using expressions, 
//            /// the first Func{TObject,TReturn} parameter must be the constant to be passed in
//            /// </summary>
//            /// <typeparam name="TFunc">Delegate Func to create</typeparam>
//            /// <param name="targetType">Type of constant to pass in to the Func</param>
//            /// <param name="methodName">Method to examine</param>
//            /// <returns>Delegate function of the specified methodname</returns>
//            /// <example>
//            /// The function Func{TType,TArg1,TArg2} with a method name of "CallMe" would create the following
//            /// lambda:
//            /// <code>
//            /// (TType, TArg1, TArg2) => TType.CallMe(TArg1, TArg2);
//            /// </code>
//            /// </example>
//            public static TFunc CreateFunc<TFunc>(Type targetType, string methodName)
//            {
//                var args = new List<ParameterExpression>();
//                MethodInfo minfo = targetType.GetMethod(methodName,
//                                                        BindingFlags.Instance | BindingFlags.Public |
//                                                        BindingFlags.SetProperty);

//                if (minfo != null)
//                {
//                    Type objectType = typeof(TFunc).GetGenericArguments().First();
//                    ParameterExpression targetParam = Expression.Parameter(objectType, "a");

//                    if (!targetType.IsAssignableFrom(objectType))
//                        throw new InvalidCastException(string.Format("{0} cannot be cast to {1}", targetType.Name,
//                                                                     objectType.Name));

//                    UnaryExpression target = Expression.Convert(targetParam, targetType);
//                    foreach (ParameterInfo arg in minfo.GetParameters())
//                        args.Add(Expression.Parameter(arg.ParameterType, arg.Name));

//                    MethodCallExpression methodinvokeExpression = Expression.Call(target, minfo, args.ToArray());
//                    Expression<TFunc> lambda = Expression.Lambda<TFunc>(methodinvokeExpression,
//                                                                        new[] { targetParam }.Concat(args));

//                    //now the following Lambda is created:
//                    // (a, TArg1, TArg2) => a.MethodName(TArg1, TArg2);

//                    return lambda.Compile();
//                }
//                return default(TFunc);
//            }

//            #region Nested type: InstanceCreator

//            private static class InstanceCreator<T>
//            {
//                public static readonly Func<T> CreateInstance =
//                    Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();

//                public static readonly Func<List<T>> CreateListInstance =
//                Expression.Lambda<Func<List<T>>>(Expression.New(typeof(List<T>))).Compile();
//            }

//            #endregion
//        }

//        #endregion
//    }
//}